import subprocess
import sys
import os
import json
import argparse
import requests
import warnings
import shlex
import re


def try_web_access(port):
    url = "https://localhost:{}/UI/Rest/Login".format(port)
    retcode = -1
    session = requests.Session()
    session.trust_env = False
    try:
        with warnings.catch_warnings():
            warnings.simplefilter(
                "ignore", category=requests.packages.urllib3.exceptions.InsecureRequestWarning)
            response = session.get(url, timeout=10, proxies={}, verify=False)
            retcode = response.status_code
    except requests.exceptions.RequestException as e:
        pass
    return retcode == 200

def read_config(config_path='config.json'):
    try:
        with open(config_path) as f:
            cfg = json.load(f)
        return cfg
    except Exception as e:
        print(f"⚠️ 读取配置文件失败: {e}, 使用默认端口")
        return {
            "mapports": {
                "https": 443,
                "ssh": 22,
                "ipmi": 623
            }
        }


def get_pid():
    try:
        output = subprocess.check_output(['ps', '-ef'], text=True)
        lines = output.split('\n')
        process = [
            line for line in lines
            if 'temp/qemu_temp/qemu_start_temp/qemu-system-aarch64-release' in line
            and 'grep' not in line
        ]
        pid = [pro.split()[1]
                for pro in process if len(pro.split()) >= 8]
        
        return pid
    except subprocess.CalledProcessError as e:
        print(f"❌ 检测现有qemu运行实例ps命令执行错误：{e}")
        return []
    except Exception as e:
        print(f"❌ 发生未知错误，{e}")
        return []

def execute():
    status = False
    config = read_config()
    web_port = config['mapports']['https']
    print("正在连接bmc...")
    pid = get_pid()
    if not pid:
        print("❌ bmc连接失败...")
        return
    while not status:
        status = try_web_access(web_port)
    
    print("✅ 连接bmc成功!")

def close_qemu():
    pid = get_pid()
    print(pid)
    if pid:
        subprocess.run(["kill", "-9", str(pid[-1])], check=True)
        print("✅ qemu已停止")

def get_eth0_ip():
    try:
        # 执行ifconfig命令并获取输出
        result = subprocess.run(['ifconfig', 'eth0'], capture_output=True, text=True, check=True)
        output = result.stdout

        # 使用正则表达式匹配IPv4地址
        ip_match = re.search(r'inet (\d+\.\d+\.\d+\.\d+)', output)
        if ip_match:
            return ip_match.group(1)
        else:
            return "127.0.0.1"
    except subprocess.CalledProcessError:
        print("❌ 无法执行ifconfig命令或eth0接口不存在")
        return "127.0.0.1"
    except Exception as e:
        print(f"⚠️ 获取eth0 IP失败: {e}, 使用默认127.0.0.1")
        return "127.0.0.1"

def run_robot_test(host_ip, user_name, password, ports, test_suite):
    """执行Robot Framework测试"""
    # 构造变量参数
    variables = [
        f"OPENUBMC_HOST:{host_ip}",
        f"OPENUBMC_USERNAME:{user_name}",
        f"OPENUBMC_PASSWORD:{password}",
        f"IPMI_PORT:{ports['ipmi']}",
        f"SSH_PORT:{ports['ssh']}",
        f"HTTP_PORT:{ports['https']}"
    ]

    # 构造robot命令
    cmd = ["robot"]
    for var in variables:
        cmd.extend(["-v", var])
    cmd.append(test_suite)

    print("执行命令:", " ".join(cmd))
    process = subprocess.Popen(
        cmd,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        text=True,
    )

    # 实时打印输出
    for line in process.stdout:
        print(line, end="")
    
    process.wait()
    return process.returncode


def testing():
    """主测试流程"""
    # 获取动态配置
    #eth0_ip = get_eth0_ip()
    #print(f"✅ eth0的IP地址是: {eth0_ip}")

    # 读取配置文件---端口信息
    config = read_config()
    ports = config['mapports']

    # 运行的测试套件
    test_suite = "test_cases/redfish/sample_redfish.robot"

    print("执行 Robot Framework 测试...")
    ret = run_robot_test(
        host_ip="127.0.0.1",
        user_name="Administrator",
        password="Admin@90000",
        ports=ports,
        test_suite=test_suite
    )

    if ret != 0:
        print("❌ 测试失败")
        close_qemu()
        exit(1)
    print("✅ 测试成功")
    close_qemu()

def install_dependency():
    # 安装tox工具
    try:
        cmd = "sudo apt-get install -y tox"
        subprocess.run(
            shlex.split(cmd),
            check=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE
        )
        print("✅ tox 安装成功")
    except subprocess.CalledProcessError as e:
        print(f"❌ 安装失败: {e.stderr}")
        close_qemu()
        sys.exit(1)
    except FileNotFoundError:
        print("❌ 找不到apt-get命令，请确保在Debian/Ubuntu系统上运行")
        close_qemu()
        sys.exit(1)

    # 安装requirements里面的依赖项
    try:
        subprocess.run(
            ["pip", "install", "-r", "requirements.txt"],
            check=True,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True,
        )
        print("✅ 依赖安装成功！")
    except subprocess.CalledProcessError as e:
        print(f"❌ 依赖安装失败！错误信息：\n{e.stderr}")
        close_qemu()
        sys.exit(1)


if __name__ == "__main__":
    install_dependency()
    execute()
    testing()
